package com.base.api.bms.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.base.api.bms.IMipsService;
import com.base.dao.bms.MipsItemUploadFailMapper;
import com.base.dao.bms.MipsPatiVisitInfoMapper;
import com.base.dao.bms.MipsUploadDetailMapper;
import com.base.dao.bms.MipsUploadInfoMapper;
import com.base.utils.HttpRequsetUtil;
import com.base.utils.ThreadLocalUtil;
import com.base.utils.WebSocketServer;
import com.base.vo.bms.MipsItemUploadFail;
import com.base.vo.bms.MipsPatiVisitInfo;
import com.base.vo.bms.MipsUploadDetail;
import com.base.vo.bms.MipsUploadInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 医保服务层
 */
@Service
public class MipsServiceImpl implements IMipsService {

    @Autowired
    private MipsPatiVisitInfoMapper mipsPatiVisitInfoMapper;
    @Autowired
    private MipsUploadDetailMapper mipsUploadDetailMapper;
    @Autowired
    private MipsItemUploadFailMapper uploadFailMapper;
    @Autowired
    private MipsUploadInfoMapper uploadInfoMapper;

    private Logger logger = LoggerFactory.getLogger(getClass());

    //本地未对照
    private static final String unContrastCode = "101";

    //明细上传医保返回失败
    private static final String failInsuranceCode = "102";

    //没有需要上传的明细
    private static final String noDetailToUploadCode = "103";

    //居民医保一次性明细上传数量
    private static final int onceUploadCountSysjm = 1000;

    //市医保一次性明细上传数量
    private static final int onceUploadCountSychi = 20;

    //省医保一次性明细上传数量
    private static final int onceUploadCountSysyb = 1;

    //akb020	定点医院编号
    private static final String akb020 = "42034020254";

    //yab300	就医地统筹区编码
    private static final String yab300 = "420800";

    //yab600	就医地分中心编码
    private static final String yab600 = "420340";

    public void msg(String msg) {
        logger.info(msg);
        WebSocketServer.sendInfo(msg, ThreadLocalUtil.getSessionId());
    }

    @Override
    public String findPatientInfoByPid(String patientId) {
        Map<String, Object> map = new HashMap<>();
        List<MipsPatiVisitInfo> list = new ArrayList<>();
        try {
            list = mipsPatiVisitInfoMapper.selectByPatientId(patientId);
            for (MipsPatiVisitInfo mipsPatiVisitInfo : list) {
                mipsPatiVisitInfo.setInsuranceSystemCode(mipsPatiVisitInfoMapper.getInsuranceSystemName(mipsPatiVisitInfo.getId()));
            }
            map.put("data", list);
            map.put("code", 0);
        } catch (Exception e) {
            map.put("code", "400");
            map.put("msg", e.getMessage());
        }
        return JSON.toJSONString(map);
    }

    @Override
    public String singleUploadBill(String mipsPatientInfoId) {

        try {
            MipsPatiVisitInfo mipsPatiVisitInfo = mipsPatiVisitInfoMapper.selectByPrimaryKey(Long.parseLong(mipsPatientInfoId));
            return singleUploadBill(mipsPatiVisitInfo);
        } catch (Exception e) {
            Map<String, Object> map = new HashMap<>();
            map.put("code", "400");
            map.put("msg", e.getMessage());
            return JSON.toJSONString(map);
        }

    }

    @Override
    public String cancelUploadBill(String mipsPatientInfoId) {
        try {
            MipsPatiVisitInfo mipsPatiVisitInfo = mipsPatiVisitInfoMapper.selectByPrimaryKey(Long.parseLong(mipsPatientInfoId));
            return cancelUploadBill(mipsPatiVisitInfo);
        } catch (Exception e) {
            Map<String, Object> map = new HashMap<>();
            map.put("code", "400");
            map.put("msg", e.getMessage());
            return JSON.toJSONString(map);
        }
    }

    @Override
    public String discharged(String mipsPatientInfoId) {
        Map<String, Object> map = new HashMap<>();
        try {
            MipsPatiVisitInfo mipsPatiVisitInfo = mipsPatiVisitInfoMapper.selectByPrimaryKey(Long.parseLong(mipsPatientInfoId));
            if (mipsPatiVisitInfo.getOutDate() != null && mipsPatiVisitInfo.getOutMajorDiagCode() != null && mipsPatiVisitInfo.getOutDate() != null) {
                return discharged(mipsPatiVisitInfo);
            } else {
                map.put("msg", "护士站还未出院，不能进行医保出院！");
            }
        } catch (Exception e) {

            map.put("msg", e.getMessage());
        }
        map.put("code", "400");
        return JSON.toJSONString(map);
    }

    @Override
    public String cancelDisCharged(String mipsPatientInfoId) {
        try {
            MipsPatiVisitInfo mipsPatiVisitInfo = mipsPatiVisitInfoMapper.selectByPrimaryKey(Long.parseLong(mipsPatientInfoId));
            return cancelDischarged(mipsPatiVisitInfo);
        } catch (Exception e) {
            Map<String, Object> map = new HashMap<>();
            map.put("code", "400");
            map.put("msg", e.getMessage());
            return JSON.toJSONString(map);
        }
    }

    public String discharged(MipsPatiVisitInfo mipsPatiVisitInfo) {
        Map<String, Object> map = new HashMap<>();
        try {
            //组装明细上传参数
            String jsonStr = "";
            if ("42030001".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                jsonStr = assemblyPara(mipsPatiVisitInfo.getInsuranceSystemCode(), "2220", assemblyDischargedParam(mipsPatiVisitInfo), mipsPatiVisitInfo.getPro2());
                msg(jsonStr);
                //调用后台
                msg("正在调用医保接口,等待返回交易结果,请稍后...");
                long start = System.currentTimeMillis();
                String result = HttpRequsetUtil.doPost(jsonStr);
                long end = System.currentTimeMillis();
                msg("调用完成,用时:".concat(String.valueOf(end - start)).concat("ms"));
                JSONObject resultSet = JSON.parseObject(result).getJSONObject("args").getJSONArray("resultSet").getJSONObject(0);
                if ("ok".equals(resultSet.getString("result"))) {
                    mipsPatiVisitInfo.setIsDischarge("1");
                    mipsPatiVisitInfoMapper.updateIsDischargeByPrimaryKey(mipsPatiVisitInfo);
                    map.put("code", "0");
                } else {   //医保返回失败
                    map.put("code", failInsuranceCode);
                    map.put("msg", resultSet.getString("Msg") == null ? resultSet.getString("jyscMsg") : resultSet.getString("Msg"));
                }
                map.put("resultSet", resultSet);
            }
            if ("42030002".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                mipsPatiVisitInfo.setIsDischarge("1");
                mipsPatiVisitInfoMapper.updateIsDischargeByPrimaryKey(mipsPatiVisitInfo);
                map.put("code", "0");
            }
            map.put("data", mipsPatiVisitInfo);
        } catch (Exception e) {
            map.put("count", 0);
            map.put("data", new ArrayList<>());
            map.put("code", 100);
            map.put("msg", "后台调用医保接口异常," + e.getMessage());
        }
        return JSON.toJSONString(map);
    }

    public String cancelDischarged(MipsPatiVisitInfo mipsPatiVisitInfo) {
        Map<String, Object> map = new HashMap<>();
        try {
            //组装明细上传参数
            String jsonStr = "";
            if ("42030001".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                jsonStr = assemblyPara(mipsPatiVisitInfo.getInsuranceSystemCode(), "2240", assemblyCancelDischargedParam(mipsPatiVisitInfo), mipsPatiVisitInfo.getPro2());
                msg(jsonStr);
                //调用后台
                msg("正在调用医保接口,等待返回交易结果,请稍后...");
                long start = System.currentTimeMillis();
                String result = HttpRequsetUtil.doPost(jsonStr);
                long end = System.currentTimeMillis();
                msg("调用完成,用时:".concat(String.valueOf(end - start)).concat("ms"));
                JSONObject resultSet = JSON.parseObject(result).getJSONObject("args").getJSONArray("resultSet").getJSONObject(0);
                if ("ok".equals(resultSet.getString("result"))) {
                    mipsPatiVisitInfo.setIsDischarge("0");
                    mipsPatiVisitInfoMapper.updateIsDischargeByPrimaryKey(mipsPatiVisitInfo);
                    map.put("code", "0");
                } else {   //医保返回失败
                    map.put("code", failInsuranceCode);
                    map.put("msg", resultSet.getString("Msg") == null ? resultSet.getString("jyscMsg") : resultSet.getString("Msg"));
                }
                map.put("resultSet", resultSet);
            }
            if ("42030002".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                mipsPatiVisitInfo.setIsDischarge("0");
                mipsPatiVisitInfoMapper.updateIsDischargeByPrimaryKey(mipsPatiVisitInfo);
                map.put("code", "0");

            }
            map.put("data", mipsPatiVisitInfo);
        } catch (Exception e) {
            map.put("count", 0);
            map.put("data", new ArrayList<>());
            map.put("code", 100);
            map.put("msg", "后台调用医保接口异常," + e.getMessage());
        }
        return JSON.toJSONString(map);
    }

    public String cancelUploadBill(MipsPatiVisitInfo mipsPatiVisitInfo) {
        Map<String, Object> map = new HashMap<>();
        try {
            //组装明细上传参数
            String jsonStr = "";
            if ("42030001".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                jsonStr = assemblyPara(mipsPatiVisitInfo.getInsuranceSystemCode(), "2340", assemblyCancelUploadParam(mipsPatiVisitInfo), mipsPatiVisitInfo.getPro2());
            }
            if ("42030002".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                jsonStr = assemblyPara(mipsPatiVisitInfo.getInsuranceSystemCode(), "33", assemblyCancelUploadParam(mipsPatiVisitInfo), mipsPatiVisitInfo.getPro2());
            }
            if ("42030003".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                jsonStr = assemblyPara(mipsPatiVisitInfo.getInsuranceSystemCode(), "10", assemblyCancelUploadParam(mipsPatiVisitInfo), mipsPatiVisitInfo.getPro2());
            }
            msg(jsonStr);
            //调用后台上传
            msg("正在调用医保接口,等待返回交易结果,请稍后...");
            long start = System.currentTimeMillis();
            String result = HttpRequsetUtil.doPost(jsonStr);
            long end = System.currentTimeMillis();
            msg("调用完成,用时:".concat(String.valueOf(end - start)).concat("ms"));
            JSONObject resultSet = JSON.parseObject(result).getJSONObject("args").getJSONArray("resultSet").getJSONObject(0);
            if ("ok".equals(resultSet.getString("result"))) {
                mipsUploadDetailMapper.updateCancelFlagByPaiVisitInfoId(String.valueOf(mipsPatiVisitInfo.getId()));
                uploadInfoMapper.updateCancelFlagByPaiVisitInfoId(String.valueOf(mipsPatiVisitInfo.getId()));
                map.put("code", "0");
            } else {   //取消明细上传医保返回失败
                map.put("code", failInsuranceCode);
            }
            map.put("msg", resultSet.getString("Msg") == null ? resultSet.getString("jyscMsg") : resultSet.getString("Msg"));
            map.put("resultSet", resultSet);
        } catch (Exception e) {
            map.put("count", 0);
            map.put("data", new ArrayList<>());
            map.put("code", 100);
            map.put("msg", "后台调用医保接口异常," + e.getMessage());
        }
        return JSON.toJSONString(map);
    }

    public String assemblyCancelUploadParam(MipsPatiVisitInfo mipsPatiVisitInfo) {
        String JsonParam = "";
        if ("42030002".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
            JsonParam += "<?xml version='1.0' encoding='GBK' standalone='yes' ?>";
            JsonParam += "<input>";
            JsonParam += "<akc190>" + mipsPatiVisitInfo.getPatiVisitIdInsurance() + "</akc190>";  //就诊流水号
            JsonParam += "<ykb065>" + mipsPatiVisitInfo.getPro2() + "</ykb065>";  //执行社会保险办法
            JsonParam += "</input>";
        } else if ("42030001".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
            JsonParam += mipsPatiVisitInfo.getPatiVisitIdInsurance() + "|"; //住院流水号(门诊流水号)|
        } else if ("42030003".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
            JsonParam += "<?xml version='1.0' encoding='GBK' standalone='yes' ?>";
            JsonParam += "<input>";
            JsonParam += "<akb020>" + akb020 + "</akb020>";  //akb020	定点医院编号 	VARCHAR2(20)	N
            JsonParam += "<yab003>" + mipsPatiVisitInfo.getPro1() + "</yab003>";  //yab003	参保地统筹区编码	VARCHAR2(6)	N	使用01交易返回yab003
            JsonParam += "<yab300>" + yab300 + "</yab300>";  //yab300	就医地统筹区编码	VARCHAR2(6)	N
            JsonParam += "<yab600>" + yab600 + "</yab600>";  //yab600	就医地分中心编码	VARCHAR2(8)	N
            JsonParam += "<akc020>" + mipsPatiVisitInfo.getCardNo() + "</akc020>";  //akc020	卡号	VARCHAR2(20) 	N
            JsonParam += "<aac001>" + mipsPatiVisitInfo.getPersonalNo() + "</aac001>";  //aac001	个人编号	VARCHAR2(20)	N
            JsonParam += "<akc190>" + mipsPatiVisitInfo.getPatiVisitIdInsurance() + "</akc190>";  //akc190	就诊登记号	VARCHAR2(19) 	N
            JsonParam += "<ykc610>" + "</ykc610>";  //ykc610	明细序号	VARCHAR2(18)	N	明细序号为空时回退全部明细记录；若有则回退对应明细序号的单条明细记录
            JsonParam += "<aae011>" + "99999" + "</aae011>";  //aae011	经办人	VARCHAR2(20)	N
            JsonParam += "<aae036>" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "</aae036>";  //aae036  	经办时间                                   	DATE	N	YYYY-MM-DD
            JsonParam += "</input>";
        }
        return JsonParam;
    }

    public String assemblyDischargedParam(MipsPatiVisitInfo mipsPatiVisitInfo) {
        String JsonParam = "";
        if ("42030001".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
            JsonParam += mipsPatiVisitInfo.getPatiVisitIdInsurance() + "|"; //住院流水号	VARCHAR2(18)	NOT NULL	唯一
            JsonParam += mipsPatiVisitInfo.getMedicalType() + "|"; //医疗类别	VARCHAR2(3)	NOT NULL
            JsonParam += "|"; //病历信息	VARCHAR2(100)
            JsonParam += mipsPatiVisitInfo.getOutArea() + "|"; //科室名称
            JsonParam += mipsPatiVisitInfo.getBedCode() + "|"; //床位号	VARCHAR2(20)
            JsonParam += mipsPatiVisitInfo.getMedicalType() + "|"; // 经办人	VARCHAR2(20)	NOT NULL	医疗机构操作员姓名
            JsonParam += mipsPatiVisitInfo.getMedicalType() + "|"; //出院日期	VARCHAR2(14)	NOT NULL	YYYYMMDDHH24MISS，医院上传数据不能为空
            JsonParam += mipsPatiVisitInfo.getOutReason() + "|"; //出院原因	VARCHAR2(3)	NOT NULL    '0'_正常治愈出院 '1'_未治愈出院 '2'_医院要求转院 '3'_病人要求转院  '4'_院内相关疾病转科治疗 '5'_院内无关疾病专科治疗 '6'_死亡
            JsonParam += mipsPatiVisitInfo.getOutMajorDiagCode() + "|"; // 出院诊断疾病编码	VARCHAR2(20)	NOT NULL	必须为中心病种编码
            JsonParam += mipsPatiVisitInfo.getOutMajorDiagName() + "|"; //出院诊断疾病名称	VARCHAR2(50)	NOT NULL
            JsonParam += "|"; //第一副诊断名称	VARCHAR2(100)
            JsonParam += "|"; //第二副诊断名称	VARCHAR2(100)
            JsonParam += "|"; //第三副诊断名称	VARCHAR2(100)
            JsonParam += "|"; //第一副诊断名称	VARCHAR2(100)
            JsonParam += "|"; //第一副诊断编码	VARCHAR2(20)		必须为中心病种编码
            JsonParam += "|"; //第一副诊断编码	VARCHAR2(20)		必须为中心病种编码
            JsonParam += "|"; //第一副诊断编码	VARCHAR2(20)		必须为中心病种编码
            JsonParam += "|"; //第一副诊断编码	VARCHAR2(20)		必须为中心病种编码
        }
        return JsonParam;
    }

    public String assemblyCancelDischargedParam(MipsPatiVisitInfo mipsPatiVisitInfo) {
        String JsonParam = "";
        if ("42030001".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
            JsonParam += mipsPatiVisitInfo.getPro1() + "|"; //发送方(医疗机构)撤销交易流水号	VARCHAR2(30)	NOT NULL
            JsonParam += "99999" + "|"; //经办员姓名	VARCHAR2(20)	NOT NULL
        }
        return JsonParam;
    }

    public String singleUploadBill(MipsPatiVisitInfo mipsPatiVisitInfo) {
        List<MipsUploadDetail> list = mipsUploadDetailMapper.selectByMipsInfoId(String.valueOf(mipsPatiVisitInfo.getId()));
        msg("根据mipsPatiVisitInfoId:" + String.valueOf(mipsPatiVisitInfo.getId()) + " 查询未上传的明细数量:" + list.size());
        Map<String, Object> map = new HashMap<>();
        List<MipsItemUploadFail> list1 = new ArrayList<>();

        //存在需要上传的明细
        if (list.size() > 0) {

            msg("开始校验是否存在未对照项目...");
            //校验是否存在未对照项目
            for (MipsUploadDetail mipsUploadDetail : list) {
                //省医保不对照
                if (("".equals(mipsUploadDetail.getInsuranceItemCode()) || mipsUploadDetail.getInsuranceItemCode() == null) && !"42030003".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                    MipsItemUploadFail itemUploadFail = new MipsItemUploadFail();
                    itemUploadFail.setBillItemId(mipsUploadDetail.getBillItemId());
                    itemUploadFail.setItemCode(mipsUploadDetail.getItemCode());
                    itemUploadFail.setItemName(mipsUploadDetail.getItemName());
                    itemUploadFail.setMipsPatVisitInfoId(mipsPatiVisitInfo.getId());
                    itemUploadFail.setOperator("99999");
                    itemUploadFail.setInsuranceSystemName(mipsPatiVisitInfoMapper.getInsuranceSystemName(mipsPatiVisitInfo.getId()));
                    itemUploadFail.setOperatDate(new Date());
                    // itemUploadFail.setMipId(Long.parseLong(mipsPatiVisitInfo.getInsuranceSystemCode()));
                    msg("未获取到项目编码【" + mipsUploadDetail.getItemCode() + "】,项目名称【" + mipsUploadDetail.getItemName() + "】的对照信息");
                    itemUploadFail.setFailMsg("未获取到项目编码【" + mipsUploadDetail.getItemCode() + "】,项目名称【" + mipsUploadDetail.getItemName() + "】的对照信息");
                    list1.add(itemUploadFail);
                }
                //totalMoney = totalMoney.add(mipsUploadDetail.getPrice());
            }


            //存在未对照的项目,直接返回
            if (list1.size() > 0) {
                msg("存在未对照的项目,直接返回...");
                uploadFailMapper.insertBatch(list1);
                map.put("code", unContrastCode);
                map.put("msg", "");
                map.put("data", list1);
                return JSON.toJSONString(map);
            } else {

                MipsUploadInfo mipsUploadInfo = new MipsUploadInfo();
                mipsUploadInfo.setId(Long.parseLong(String.valueOf(uploadInfoMapper.getSquence(1))));
                msg("获取上传明细主表序列: " + mipsUploadInfo.getId());
                mipsUploadInfo.setCancelFlag("0");
                mipsUploadInfo.setOperateDate(new Date());
                mipsUploadInfo.setMipsPatVisitInfoId(mipsPatiVisitInfo.getId());
                mipsUploadInfo.setOperator("99999");
                BigDecimal totalMoney = new BigDecimal("0");
                int count = 100;
                if ("42030002".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                    count = onceUploadCountSysjm;
                }
                if ("42030001".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                    count = onceUploadCountSychi;
                }
                if ("42030003".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                    count = onceUploadCountSysyb;
                }
                List<List<MipsUploadDetail>> lists = splitList(list, count);
                msg("开始分割明细,需要上传数量：" + list.size() + ",单次上传数量:" + count);
                map.put("code", "0");
                String msg = "";
                for (int i = 0; i < lists.size(); i++) {

                    List<MipsUploadDetail> list2 = lists.get(i);
                    try {
                        msg("正在组装明细上传参数...");
                        //组装明细上传参数
                        String jsonStr = "";
                        if ("42030001".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                            jsonStr = assemblyPara(mipsPatiVisitInfo.getInsuranceSystemCode(), "2310", assemblyUploadParam(mipsPatiVisitInfo, list2), mipsPatiVisitInfo.getPro2());
                        }
                        if ("42030002".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                            jsonStr = assemblyPara(mipsPatiVisitInfo.getInsuranceSystemCode(), "31", assemblyUploadParam(mipsPatiVisitInfo, list2), mipsPatiVisitInfo.getPro2());
                        }
                        if ("42030003".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
                            jsonStr = assemblyPara(mipsPatiVisitInfo.getInsuranceSystemCode(), "03", assemblyUploadParam(mipsPatiVisitInfo, list2), mipsPatiVisitInfo.getPro2());
                        }
                        for (int j = 0; j < list2.size(); j++) {
                            list2.get(j).setMajorId(mipsUploadInfo.getId());
                            totalMoney = totalMoney.add(list2.get(j).getAmount());
                        }
                        msg(jsonStr);
                        //调用后台上传
                        //msg("正在调用医保接口,等待返回交易结果,请稍后...");
                        msg("共需要上传数量: " + list.size() + " , 正在上传: " + (i + 1) + "/" + lists.size() + " 批明细...");
                        long start = System.currentTimeMillis();
                        String result = HttpRequsetUtil.doPost(jsonStr);
                        long end = System.currentTimeMillis();
                        msg("调用完成,用时:".concat(String.valueOf(end - start)).concat("ms"));
                        msg(result);
                        JSONObject resultSet = JSON.parseObject(result).getJSONObject("args").getJSONArray("resultSet").getJSONObject(0);
                        map.put("resultSet", resultSet);
                        if ("ok".equals(resultSet.getString("result"))) {
                            if (mipsUploadInfo.getTotalMoney() == null) {
                                mipsUploadInfo.setTotalMoney(totalMoney);
                                uploadInfoMapper.insertSelective(mipsUploadInfo);
                            } else {
                                mipsUploadInfo.setTotalMoney(totalMoney);
                                uploadInfoMapper.updateByPrimaryKeySelective(mipsUploadInfo);
                            }
                            mipsUploadDetailMapper.insertBatch(list2);
                        } else {   //明细上传医保返回失败
                            map.put("code", failInsuranceCode);
                            msg += "批次 " + (i + 1) + " 上传失败：".concat(resultSet.getString("Msg") == null ? resultSet.getString("jyscMsg") : resultSet.getString("Msg")) + "\n\r";
                            map.put("msg", msg);
                            List<MipsItemUploadFail> failList = new ArrayList<>();
                            for (MipsUploadDetail mipsUploadDetail : list2) {
                                MipsItemUploadFail itemUploadFail = new MipsItemUploadFail();
                                itemUploadFail.setBillItemId(mipsUploadDetail.getBillItemId());
                                itemUploadFail.setItemCode(mipsUploadDetail.getItemCode());
                                itemUploadFail.setItemName(mipsUploadDetail.getItemName());
                                itemUploadFail.setMipsPatVisitInfoId(mipsPatiVisitInfo.getId());
                                itemUploadFail.setOperator("99999");
                                itemUploadFail.setInsuranceSystemName(mipsPatiVisitInfoMapper.getInsuranceSystemName(mipsPatiVisitInfo.getId()));
                                itemUploadFail.setOperatDate(new Date());
                                // itemUploadFail.setMipId(Long.parseLong(mipsPatiVisitInfo.getInsuranceSystemCode()));
                                //msg("未获取到项目编码【" + mipsUploadDetail.getItemCode() + "】,项目名称【" + mipsUploadDetail.getItemName() + "】的对照信息");
                                itemUploadFail.setFailMsg(resultSet.getString("Msg") == null ? resultSet.getString("jyscMsg") : resultSet.getString("Msg"));
                                failList.add(itemUploadFail);
                            }

                            if (!failList.isEmpty()) {
                                uploadFailMapper.insertBatch(failList);
                            }
                        }

                    } catch (Exception e) {
                        map.put("count", 0);
                        map.put("data", new ArrayList<>());
                        map.put("code", 100);
                        map.put("msg", "后台调用医保接口异常," + e.getMessage());
                        return JSON.toJSONString(map);
                    }
                }

                //map.put("Data", resultSet);
            }

        } else {  //没有需要上传的明细
            map.put("code", noDetailToUploadCode);
            map.put("msg", "没有需要上传的明细");
        }
        return JSON.toJSONString(map);
    }

    public List<List<MipsUploadDetail>> splitList(List<MipsUploadDetail> list, int len) {
        if (list == null || list.size() == 0 || len < 1) {
            return null;
        }
        List<List<MipsUploadDetail>> result = new ArrayList<List<MipsUploadDetail>>();
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i < count; i++) {
            List<MipsUploadDetail> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
            result.add(subList);
        }
        return result;
    }

    /**
     * 组装医保交易入参
     *
     * @param yblx      医保类型 42030001
     * @param jybh      交易编号
     * @param jysrParam 交易输入
     * @param areaCode  市医保区域编码
     * @return
     */
    public String assemblyPara(String yblx, String jybh, String jysrParam, String areaCode) {
        String action = "";
        String commandSet = "";

        if ("42030002".equals(yblx)) {
            action = "SYPMEDICARE_CALL";
            commandSet = "\"Jybh\":\"" + jybh + "\",\"JysrXml\":\"" + jysrParam + "\"";
        } else if ("42030001".equals(yblx)) {
            action = "SY_JINBAO_CALL";
            jysrParam = jybh + "^" + areaCode + "^99999^^" + System.currentTimeMillis() + "^0000^" + jysrParam + "^";
            commandSet = "\"areaCode\":\"" + areaCode + "\",\"jybh\":\"" + jybh + "\",\"jysrParam\":\"" + jysrParam + "\"";
        } else if ("42030003".equals(yblx)) {
            action = "PMEDICARE_CALL";
            commandSet = "\"Jybh\":\"" + jybh + "\",\"JysrXml\":\"" + jysrParam + "\"";
        }

        String result = "{\"action\":\"" + action + "\",\"args\":{\"params\":{\"filePath\": \"\"},\"commandSet\":[{" + commandSet + "}]}}";
        return result;
    }

    /**
     * 组装明细上传的交易输入
     *
     * @param mipsPatiVisitInfo 医保登记信息表记录
     * @param list              需要上传的费用明细
     * @return
     */
    public String assemblyUploadParam(MipsPatiVisitInfo mipsPatiVisitInfo, List<MipsUploadDetail> list) {
        String JsonParam = "";
        if ("42030002".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
            JsonParam += "<?xml version='1.0' encoding='GBK' standalone='yes' ?>";
            JsonParam += "<input>";
            JsonParam += "<akc190>" + mipsPatiVisitInfo.getPatiVisitIdInsurance() + "</akc190>";  //就诊流水号
            JsonParam += "<ykb065></ykb065>";  //执行社会保险办法
            JsonParam += "<dataset>";
            for (MipsUploadDetail mipsUploadDetail : list) {
                JsonParam += "<row>";
                JsonParam += "<yka105>" + mipsUploadDetail.getBillItemId() + "</yka105>"; //记账流水号
                JsonParam += "<ake005>" + mipsUploadDetail.getItemCode() + "</ake005>";  //医疗机构目录编码
                JsonParam += "<ake006>" + mipsUploadDetail.getItemName() + "</ake006>";   //医疗机构目录名称
                JsonParam += "<ake001>" + mipsUploadDetail.getInsuranceItemCode() + "</ake001>";   //社保三大目录编码
                JsonParam += "<ake002>" + mipsUploadDetail.getItemCode() + "</ake002>";   //社保三大目录名称
                JsonParam += "<akc226>" + mipsUploadDetail.getQuantity() + "</akc226>";   //数量
                JsonParam += "<akc225>" + mipsUploadDetail.getPrice() + "</akc225>";   //实际价格
                JsonParam += "<yka315>" + mipsUploadDetail.getAmount() + "</yka315>";   //明细项目费用总额
                JsonParam += "<aka074>" + mipsUploadDetail.getSpec() + "</aka074>";   //规格
                JsonParam += "<yae374></yae374>";   //剂型名称
                JsonParam += "<yke201></yke201>";   //中药使用方式  见57交易代码
                JsonParam += "<yke186></yke186>";   //医院审批标志  见57交易代码
                JsonParam += "<yke356></yke356>";   //药物供应商
                JsonParam += "<yke357></yke357>";   //药物生产批号
                JsonParam += "<yke672></yke672>";   //药物有效期
                JsonParam += "<bke019></bke019>";   //包装
                JsonParam += "<bke020></bke020>";   //材质
                JsonParam += "<bke011></bke011>";   //用法
                JsonParam += "<bke012></bke012>";   //用量
                JsonParam += "<yke676></yke676>";   //外检标志 见57交易代码
                JsonParam += "<yke677></yke677>";   //外检医院编码
                DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                if (mipsUploadDetail.getTallyDate() != null) {
                    JsonParam += "<ake007>" + dfm.format(mipsUploadDetail.getTallyDate()) + "</ake007>";
                } else {
                    JsonParam += "<ake007></ake007>";  //费用发生日期
                }
                JsonParam += "<aae011></aae011>";   //经办人编码
                JsonParam += "<ykc141></ykc141>";   //经办人姓名
                JsonParam += "<akc220></akc220>";   //处方单据号
                JsonParam += "<akc221></akc221>";   //处方单据时间
                JsonParam += "<aka081></aka081>";   //用药途径
                JsonParam += "<ake135></ake135>";   //常规用量
                JsonParam += "<aka072></aka072>";   //用药频次
                JsonParam += "<aka071></aka071>";   //单次用量
                JsonParam += "<akc229></akc229>";   //用药天数
                JsonParam += "<akc231></akc231>";   //药量天数
                JsonParam += "<yka097></yka097>";   //开单科室编码
                JsonParam += "<yka098></yka098>";   //开单科室名称
                JsonParam += "<ykd102></ykd102>";   //开单医生编码
                JsonParam += "<yka099></yka099>";   //开单医生姓名
                JsonParam += "</row>";
            }
            JsonParam += "</dataset>";
            JsonParam += "</input>";
        } else if ("42030001".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
            //JsonParam += jybh + "^" + qybm + "^10882^^" + System.currentTimeMillis() + "^0000^";
            for (int i = 0; i < list.size(); i++) {
                MipsUploadDetail mipsUploadDetail = list.get(i);
                JsonParam += mipsPatiVisitInfo.getPatiVisitIdInsurance() + "|"; //住院流水号(门诊流水号)|
                JsonParam += mipsUploadDetail.getInsuranceItemClass() + "|"; //项目类别|
                JsonParam += "|"; //费用类别|
                if (mipsUploadDetail.getQuantity().compareTo(BigDecimal.ZERO) < 0) {
                    JsonParam += mipsUploadDetail.getMemo() + "|"; //处方号|
                } else {
                    JsonParam += mipsUploadDetail.getBillItemId() + "|"; //处方号|
                }

                DateFormat dfm = new SimpleDateFormat("yyyyMMddhhmmss");
                JsonParam += dfm.format(mipsUploadDetail.getTallyDate()) + "|"; //处方日期|
                JsonParam += mipsUploadDetail.getItemCode() + "|";  //医院收费项目内码|
                JsonParam += mipsUploadDetail.getInsuranceItemCode() + "|";  //收费项目中心编码|
                JsonParam += mipsUploadDetail.getItemName() + "|";  //医院收费项目名称|
                JsonParam += mipsUploadDetail.getPrice() + "|";  //单价|
                JsonParam += mipsUploadDetail.getQuantity() + "|";  //数量|
                JsonParam += "|";  //剂型|
                JsonParam += "|";  //规格|
                JsonParam += "|";  //每次用量|
                JsonParam += "|"; // 使用频次|";
                JsonParam += "|";  //医生姓名|
                JsonParam += "|";  //处方医师|
                JsonParam += "|";  //用法|
                JsonParam += "|";  //单位|
                JsonParam += "|";  //科别名称|
                JsonParam += "|";  //执行天数|
                JsonParam += "|";  //草药单复方标志|
                JsonParam += "|";  //经办人|
                JsonParam += "|";  //优惠单价|
                if (i != list.size() - 1) {
                    JsonParam += "$";
                }
            }
        } else if ("42030003".equals(mipsPatiVisitInfo.getInsuranceSystemCode())) {
            for (MipsUploadDetail mipsUploadDetail : list) {
                JsonParam += "<?xml version='1.0' encoding='GBK' standalone='yes' ?>";
                JsonParam += "<input>";
                JsonParam += "<akb020>" + akb020 + "</akb020>";  //akb020	定点医院编号 	VARCHAR2(20)	N
                JsonParam += "<yab003>" + mipsPatiVisitInfo.getPro1() + "</yab003>";  //yab003	参保地统筹区编码	VARCHAR2(6)	N
                JsonParam += "<yab300>" + yab300 + "</yab300>";  //yab300	就医地统筹区编码	VARCHAR2(6)	N
                JsonParam += "<yab600>" + yab600 + "</yab600>";  //yab600	就医地分中心编码	VARCHAR2(6)	N
                JsonParam += "<akc020>" + mipsPatiVisitInfo.getCardNo() + "</akc020>";  //akc020	卡号	VARCHAR2(20) 	N
                JsonParam += "<aac001>" + mipsPatiVisitInfo.getPersonalNo() + "</aac001>";  //aac001	个人编号	VARCHAR2(20)	N
                JsonParam += "<akc190>" + mipsPatiVisitInfo.getPatiVisitIdInsurance() + "</akc190>";  //akc190	就诊登记号	VARCHAR2(19) 	N
                JsonParam += "<akc220>" + mipsUploadDetail.getBillItemId() + "</akc220>";  //akc220	处方号	VARCHAR2(18) 	N
                JsonParam += "<ykc610>" + mipsUploadDetail.getBillItemId() + "</ykc610>";  //ykc610	明细序号	VARCHAR2(18)	N	同处方下必须唯一
                JsonParam += "<akc515>" + mipsUploadDetail.getItemCode() + "</akc515>";  //akc515	医院项目编码	VARCHAR2(20)	N
                JsonParam += "<akc516>" + mipsUploadDetail.getItemName() + "</akc516>";  //akc516	医院项目名称	VARCHAR2(100)	N
                JsonParam += "<akc226>" + mipsUploadDetail.getQuantity() + "</akc226>";  //akc226	数量	NUMBER(8,2)	N
                JsonParam += "<akc225>" + mipsUploadDetail.getPrice() + "</akc225>";  //akc225	单价	NUMBER(14,4)	N
                JsonParam += "<akc227>" + mipsUploadDetail.getAmount() + "</akc227>";  //akc227	费用总额	NUMBER(14, 2)	N	数量*单价不等于费用总额时，以费用总额为准
                JsonParam += "<ykc611>" + "</ykc611>";  //ykc611	产地	VARCHAR2(128)	Y
                JsonParam += "<aka074>" + mipsUploadDetail.getSpec() + "</aka074>";  //aka074	规格	VARCHAR2(50)	Y
                JsonParam += "<aka067>" + mipsUploadDetail.getUnit() + "</aka067>";  //aka067	单位	VARCHAR2(30)	Y
                JsonParam += "<aka070>" + "</aka070>";  //aka070	剂型	VARCHAR2(50)	Y
                JsonParam += "<ykc726>" + "</ykc726>";  //ykc726	草药单复方标志	VARCHAR2(3)	Y
                JsonParam += "<ykc612>" + "</ykc612>";  //ykc612	处方医生编码	VARCHAR2(20)	N
                JsonParam += "<ykc613>" + "</ykc613>";  //ykc613	处方医生姓名	VARCHAR2(20)	N
                JsonParam += "<aaz307>" + "</aaz307>";  //aaz307	科室编码	VARCHAR2(16)	N
                JsonParam += "<ykc011>" + "</ykc011>";  //ykc011	科室名称	VARCHAR2(60)	N
                DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                if (mipsUploadDetail.getTallyDate() != null) {
                    JsonParam += "<akc221>" + dfm.format(mipsUploadDetail.getTallyDate()) + "</akc221>";
                } else {
                    JsonParam += "<akc221></akc221>";  //费用发生日期
                }
                //akc221	收费时间	DATE YYYY-MM-DD HH24:MI:SS	N	与患者明细费用实际发生时间一致
                JsonParam += "<aae011>" + "AutoUpload" + "</aae011>";  //aae011	经办人	VARCHAR2(20)	N
                JsonParam += "<aae036>" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "</aae036>";  //aae036	经办时间	DATE	N	YYYY-MM-DD
                JsonParam += "</input>";
            }

        }
        return JsonParam;
    }


}
